package cn.net.xyan.easy.spring.core.utils;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;

import java.util.*;

/**
 * Created by xiashenpin on 16/1/16.
 */
public class JsonHelper {

    static ObjectMapper objectMapper ;

    static public JavaType ClassSet = collectionType(Set.class,Class.class);
    static public JavaType ClassList = listType(Class.class);

    static public JavaType StringSet = collectionType(Set.class,String.class);
    static public JavaType StringList = listType(String.class);

    static public JavaType StringStringMap = mapType(String.class,String.class);
    static public JavaType StringObjectMap = mapType(String.class,Object.class);
    static public JavaType StringClasstMap = mapType(String.class,Class.class);

    static public JavaType javaType(Class<?> cls){
        return objectMapper().getTypeFactory().uncheckedSimpleType(cls);
    }

    static public JavaType mapType(Class<?> keyCls, Class<?> valueCls){
        return objectMapper().getTypeFactory().constructMapType(Map.class,keyCls,valueCls);
    }

    static public JavaType mapType(Class<?> keyCls, JavaType valueType){
        JavaType keyType = javaType(keyCls);
        return mapType(keyType,valueType);
    }

    static public JavaType mapType(JavaType keyType, JavaType valueType){
        return objectMapper().getTypeFactory().constructMapLikeType(Map.class,keyType,valueType);
    }

    static public JavaType collectionType(Class<? extends Collection> collectionCls, Class<?> valueCls){
        return objectMapper().getTypeFactory().constructCollectionType(collectionCls,valueCls);
    }

    static public JavaType collectionType(Class<? extends Collection> collectionCls, JavaType valueType){
        return objectMapper().getTypeFactory().constructCollectionType(collectionCls,valueType);
    }

    static public JavaType listType(Class<?> valueCls){
        return collectionType(List.class,valueCls);
    }

    static public JavaType listType(JavaType valueType){
        return collectionType(List.class,valueType);
    }

    static public JavaType genericType(Class<?> genericCls, Class<?> ... classes){
        return objectMapper().getTypeFactory().constructParametrizedType(genericCls,genericCls,classes);
    }

    static public JavaType genericType(Class<?> genericCls, JavaType ... types){
        return objectMapper().getTypeFactory().constructParametrizedType(genericCls,genericCls,types);
    }


    public static ObjectMapper objectMapper(){
        if (objectMapper == null) {
            SimpleModule module = new SimpleModule();
            //module.addSerializer(Float.class, new MoneyFloatSerializer());

            module.addSerializer(Class.class,new JavaClassSerializer());
            module.addDeserializer(Class.class,new JavaClassDeserializer());

            module.addSerializer(Date.class,new DateSerializer());
            module.addDeserializer(Date.class,new DateDeserializer());

            objectMapper = new ObjectMapper();
            objectMapper.setTimeZone(TimeZone.getTimeZone("UTC"));

            objectMapper.registerModule(module);


        }
        return objectMapper;
    }
}
